/**
 * BaseAction.java
 * Product:BaseLayer
 * Version:1.0
 * Copyright 2009 by DNE
 * All Rights Reserved.
 */
package com.site.util.base.action;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.CookiesAware;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.interceptor.ServletResponseAware;
import org.apache.struts2.interceptor.SessionAware;
import org.extremecomponents.table.limit.Limit;

import com.alibaba.fastjson.JSONObject;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.Preparable;
import com.site.util.StringUtils;
import com.site.util.base.businessbean.FileBean;
import com.site.util.base.dto.User;
import com.site.util.common.fileupload.FileUploadHandle;
import com.site.util.constant.Constants;
import com.site.util.exception.ApplicationException;
import com.site.util.extremetable.ExtremeTablePageUtil;
import com.site.util.extremetable.QueryPage;

/**
 * 该类做为所有Action的基类,所有的action都应该继承此类。
 * 便于异常处理，文件上传，分页显示等多种功能的实现。
 * 
 * 在使用服务器端验证器时，如果某些方法不需要验证，则使用注解：@SkipValidation

 */

@SuppressWarnings("all")
public abstract class BaseAction extends ActionSupport implements Preparable,SessionAware,ServletRequestAware,ServletResponseAware,CookiesAware{
	
	protected Log log=LogFactory.getLog(this.getClass());
	
	protected Map<String,Object> sessionMap;
	
	protected Map<String,Object> cookiesMap;
	
	protected HttpServletRequest request;
	
	protected HttpServletResponse response;
	
	public static final String ROOT_DIR_KEY="ecom.file.upload.root.dir";
	public static final String LINUX_ROOT_DIR_KEY="ecom.file.upload.root.dir.linux";
	public static final String DIST_DIR_KEY="ecom.file.upload.dist.dir";
	public static final String LINUX_DIST_DIR_KEY="ecom.file.upload.dist.dir.linux";
	public static final String ADV_DIR_KEY="ecom.file.upload.adv.dir";
	public static final String LINUX_ADV_DIR_KEY="ecom.file.upload.adv.dir.linux";
	
	public static final String ROOT_DIR_KEY_FOR_SERVICE = "ecom.file.upload.root.dir.for.service";
	public static final String LINUX_ROOT_DIR_KEY_FOR_SERVICE = "ecom.file.upload.root.dir.linux.for.service";
	
	//当前登录用户信息
	public User currentUser;
	
	public QueryPage getQueryPage() {
		return queryPage;
	}

	public void setQueryPage(QueryPage queryPage) {
		this.queryPage = queryPage;
	}

	//分页组件对象
	private Limit limit;
	
	//封闭了分页处理数据（如：当前页，每页显示记录数，排序等等）
	protected QueryPage queryPage;
	
	//分页时，每页显示记录数，可以在各自的action中配制
	protected int pageSize;
	
	//文件上传时，设置允许上传的文件类型，直接配文件的后缀。
	protected String fileAllowedTypes;
	
	//文件上传时，允许上传的每个文件大小（单位：KB）
	protected long fileMaxSize;
	
	//设置文件上传目录（注意：路径需要以/结尾）
	protected String uploadDir;
	
	//如果做文件上传时，表单的文件域名必须是files
	protected List<File> files;
	
	//上传临时文件的文件名
	protected List<String> filesFileName;
	//上传文件contentType类型
	protected List<String> filesContentType;
	
	protected static final String HOME="homePage";
	protected static final String LOGIN="loginPage";
	protected static final String WEBLOGIN="webloginPage";
	private String urlMenu;
	
	/*
	 * 成功消息返回页面
	 */
	private String backurl;
	/*
	 * 操作消息ID
	 */
	private String messageID;
	/*
	 * 操作消息动态显示参数，多个参数是，有","分割
	 */
	private String params;
	
	/*
	 *文件上传根路径 
	 */
	private static String rootDir;
	
	/*
	 *分布文件根路径 
	 */
	private static String distDir;
	
	/*
	 *分布文件根路径 
	 */
	private static String advDir;
	
	/**
	 * 分页查询完数据后调用此方法。
	 * 将分页查询结果相关参数存储到分布组件中，用于页面显示。
	 */
	protected void finishPagination() {
		//存储用于分页组件的数据
		limit.setRowAttributes(queryPage.getRecordCount(), limit.getCurrentRowsDisplayed());
		request.setAttribute("totalRows", new Integer(queryPage.getRecordCount()));
		request.setAttribute("currentRowsDisplayed",new Integer(limit.getCurrentRowsDisplayed()));
		log.debug("exatremetable result:" + limit.getTotalRows() +",page:" + limit.getPage()+" rowsdisplayed "+ limit.getCurrentRowsDisplayed());
	}
	
	/**
	 * 分页查询前，先调用此方法。
	 * 将分页相当参数存储到queryPage，用于DAO层分页查询
	 */
	protected void initPagination() {
		//读取页面参数，用于分页查询
		if( this.pageSize == 0) {
			this.pageSize = QueryPage.DEFAULT_PAGE_SIZE;
		}
		limit = ExtremeTablePageUtil.getLimit(request, pageSize);
		queryPage = new QueryPage(limit);
	}
	
	/**
	 * 手机商品分页查询前，先调用此方法。
	 * 将分页相当参数存储到queryPage，用于DAO层分页查询
	 */
	protected void initPagination2() {
		//读取页面参数，用于分页查询
		if( this.pageSize == 0) {
			this.pageSize = QueryPage.MOBILE_DEFAULT_PAGE_SIZE;
		}
		limit = ExtremeTablePageUtil.getLimit(request, pageSize);
		queryPage = new QueryPage(limit);
	}
	
	/*
	 * 覆盖struts取国际化方法，直接返回KEY。
	 * struts默认去properties文件中找国际化消息，覆盖此类直接返回key值，以便于去XML中找国际化消息。
	 * (non-Javadoc)
	 * @see com.opensymphony.xwork2.ActionSupport#getText(java.lang.String)
	 */
	@Override
	public String getText(String textName) {
		return textName;
	}
	
	
	/*
	 * 如果在action方法执行前需要处理一些数据，可以覆盖此方法
	 */
	public void prepare() throws Exception {
		
	}


	/*
	 * 表单与struts action属性绑定的时，如果类型转换出异常。将通过此方法捕捉
	 * 这里直接返回key值
	 * key值为：invalid.fieldvalue.属性名
	 * (non-Javadoc)
	 * @see com.opensymphony.xwork2.ActionSupport#getText(java.lang.String, java.lang.String)
	 */
	@Override
	public String getText(String textName, String defaultValue) {
		return textName;
	}
	
	public void setSession(Map sessionMap) {
		this.sessionMap=sessionMap;
	}
	
	public void setServletResponse(HttpServletResponse response) {
		this.response=response;
	}
	
	public void setServletRequest(HttpServletRequest request) {
		this.request=request;
	}
	
	@Override
	public void setCookiesMap(Map cookiesMap) {
		this.cookiesMap = cookiesMap;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public int getPageSize() {
		return pageSize;
	}

	public String getFileAllowedTypes() {
		return fileAllowedTypes;
	}

	public void setFileAllowedTypes(String fileAllowedTypes) {
		this.fileAllowedTypes = fileAllowedTypes;
	}

	public long getFileMaxSize() {
		return fileMaxSize;
	}

	public void setFileMaxSize(long fileMaxSize) {
		this.fileMaxSize = fileMaxSize;
	}

	public String getUploadDir() {
		return uploadDir;
	}

	public void setUploadDir(String uploadDir) {
		this.uploadDir = uploadDir;  //写死的 getUploadRootDir()+uploadDir+"/";
	}
	
	public void setUploadDirForService(String uploadDir) {
		this.uploadDir = getUploadRootDirForService() + uploadDir + "/";
	}
	
	public String getUploadRootDir()
	{
		//System.out.println("System.getProperty(\"os.name\"):"+System.getProperty("os.name"));
//		if(rootDir==null)
//		{
			//System.getProperty("os.name");//得到操作系统名字
			//System.getProperty("sun.os.patch.level");//得到操作系统版本
			//System.getProperty("sun.cpu.isalist");//得到CPU系统信息 
			//if(System.getProperty("os.name"))//得到操作系统名字 )
			//	{
			if(System.getProperty("os.name").startsWith("Windows"))
			{
				//System.out.println(System.getProperty("os.name"));
				//rootDir=PropertyUtil.getPropertyValueByKey(ROOT_DIR_KEY,request);
				//System.out.println("linux upload path:"+System.getProperty(rootDir));
			}
			else
			{
				
				//System.out.println(System.getProperty("os.name2222"));
				//rootDir=PropertyUtil.getPropertyValueByKey(LINUX_ROOT_DIR_KEY,request);
			//	System.out.println("linux upload path:"+rootDir);
			}
//		}
		//System.out.println("linux upload path33333:"+rootDir);
		return rootDir;
	}
	
	public String getUploadRootDirForService() {
//		if(rootDir==null) {
			if(System.getProperty("os.name").startsWith("Windows")) {
				//rootDir = PropertyUtil.getPropertyValueByKey(ROOT_DIR_KEY_FOR_SERVICE,request);
			} else {
				//rootDir = PropertyUtil.getPropertyValueByKey(LINUX_ROOT_DIR_KEY_FOR_SERVICE,request);
			}
//		}
		return rootDir;
	}

	public List<File> getFiles() {
		return files;
	}

	public void setFiles(List<File> files) {
		this.files = files;
	}

	public List<String> getFilesFileName() {
		return filesFileName;
	}

	public void setFilesFileName(List<String> filesFileName) {
		this.filesFileName = filesFileName;
	}

	public List<String> getFilesContentType() {
		return filesContentType;
	}

	public void setFilesContentType(List<String> filesContentType) {
		this.filesContentType = filesContentType;
	}

	/**
	 * 获取当前登录用户信息
	 * @return
	 */
	public User getCurrentUser() {
		if(currentUser==null)
		{
			currentUser=(User)request.getSession().getAttribute(Constants.LOGIN_USER_BACKEND);
		}
		return currentUser;
	}

	public void setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
	}
	/**
	 * 保存登陆成功后的用户到session里面去
	 * @param currentUser
	 */
	public void keepCurrentUser(User currentUser) {
		request.getSession().setAttribute(Constants.LOGIN_USER_BACKEND, currentUser);
	}
	/**
	 * 清楚session的用户
	 */
	public void clearCurrentUser() {
		request.getSession().setAttribute(Constants.LOGIN_USER_BACKEND, null);
	}
	
	public void remURL()
	{
		User curUser = getCurrentUser();
		if (curUser == null) {
			String url=request.getRequestURI();
			//url=url.substring(url.indexOf("/",1));
			String contextPath=request.getContextPath();
			url=url.substring(contextPath.length());
			
			Map paraMap=request.getParameterMap();
			if(paraMap.size()>0)
			{
				url+="?";
				for(Object o : paraMap.keySet())
				{
					Object value=(Object)paraMap.get(o);
					url+=o.toString()+"="+URLEncoder.encode(request.getParameter(o.toString())+"&");
				}
			}
			if (url.endsWith(URLEncoder.encode("&"))) {
				url = url.substring(0, url.lastIndexOf(URLEncoder.encode("&")));
			}
			request.setAttribute("req_url", url);
			if(!request.isRequestedSessionIdValid())
				addActionError("登陆超时，请重新登录");
		}
	}
	
	/**
	 * 处理上传文件
	 * 如果需要上传，只要在action中调用此方法，但页面表单文件域名称必须为files
	 * 调用此方法结束后，返回一个存放所有上传文件的集合。
	 * @return
	 */
	public List<FileBean> handleUploadFile() {
		List<FileBean> fileList=new ArrayList<FileBean>();
		try {
			if (files == null) {
				return fileList;
			}
			for (int i = 0; i < files.size(); i++) {
				FileBean fileBean = updateFile(i);
				fileList.add(fileBean);
			}
		}catch (Exception e) {
			e.printStackTrace();
			//将文件上传的异常传换成应用异常。
			throw new ApplicationException(e.getMessage(),e);
		}
		return fileList;
	}

	protected FileBean updateFile(int i) {
		FileUploadHandle uploadHandle=new FileUploadHandle();
		uploadHandle.setNeedChangeFileName(FileUploadHandle.YES);
		uploadHandle.setRequest(request);
		uploadHandle.setSrcFile(files.get(i));
		uploadHandle.setSrcFileName(filesFileName.get(i));
		//uploadHandle.setSrcFileName(numberMachine.getPictureCode()+filesFileName.get(i).substring(filesFileName.get(i).lastIndexOf(".")));
		uploadHandle.setUploadDir(uploadDir);
		uploadHandle.setAllowedTypes(fileAllowedTypes);
		uploadHandle.setMaxSize(fileMaxSize);
		uploadHandle.upload();
		FileBean fileBean=new FileBean();
		fileBean.setNewName(uploadHandle.getDestFileName());
		fileBean.setOldName(uploadHandle.getSrcFileName());
		fileBean.setSize(uploadHandle.getSrcFile().length());
		fileBean.setSuffix(uploadHandle.getSuffix());
//				String path=uploadHandle.getContextPath()==null?uploadHandle.getUploadDir():uploadHandle.getContextPath();
		String path = uploadHandle.getUploadDir();
		fileBean.setUrl(path+uploadHandle.getDestFileName());
		return fileBean;
	}
	
	protected FileBean uploadFile(File file,String fileName) {
		FileUploadHandle uploadHandle=new FileUploadHandle();
		FileBean fileBean=null;
		/*try {*/
			uploadHandle.setNeedChangeFileName(FileUploadHandle.NO);
			uploadHandle.setRequest(request);
			uploadHandle.setSrcFile(file);
			//uploadHandle.setSrcFileName(fileName);
			//uploadHandle.setSrcFileName(numberMachine.getPictureCode()+fileName.substring(fileName.lastIndexOf(".")));
			uploadHandle.setUploadDir(uploadDir);
			uploadHandle.setAllowedTypes(fileAllowedTypes);
			uploadHandle.setMaxSize(fileMaxSize);
			uploadHandle.upload();
			fileBean = new FileBean();
			fileBean.setNewName(uploadHandle.getDestFileName());
			fileBean.setOldName(uploadHandle.getSrcFileName());
			fileBean.setSize(uploadHandle.getSrcFile().length());
			fileBean.setSuffix(uploadHandle.getSuffix());
//				String path=uploadHandle.getContextPath()==null?uploadHandle.getUploadDir():uploadHandle.getContextPath();
			String path = uploadHandle.getUploadDir();
			fileBean.setUrl(path+uploadHandle.getDestFileName());
		/*} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		return fileBean;
	}
	
	
	/**
	 * 文件上传，不改变其文件名称
	 * @param file
	 * @param fileName
	 * @return
	 */
	protected FileBean uploadFile2(File file,String fileName) {
		FileUploadHandle uploadHandle=new FileUploadHandle();
		FileBean fileBean=null;
		/*try {*/
			uploadHandle.setNeedChangeFileName(FileUploadHandle.NO);
			uploadHandle.setRequest(request);
			uploadHandle.setSrcFile(file);
			//uploadHandle.setSrcFileName(fileName);
			uploadHandle.setSrcFileName(fileName);
			uploadHandle.setUploadDir(uploadDir);
			uploadHandle.setAllowedTypes(fileAllowedTypes);
			uploadHandle.setMaxSize(fileMaxSize);
			uploadHandle.upload();
			fileBean = new FileBean();
			fileBean.setNewName(uploadHandle.getDestFileName());
			fileBean.setOldName(uploadHandle.getSrcFileName());
			fileBean.setSize(uploadHandle.getSrcFile().length());
			fileBean.setSuffix(uploadHandle.getSuffix());
//				String path=uploadHandle.getContextPath()==null?uploadHandle.getUploadDir():uploadHandle.getContextPath();
			String path = uploadHandle.getUploadDir();
			fileBean.setUrl(path+uploadHandle.getDestFileName());
		/*} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}*/
		return fileBean;
	}
	
	/**
	 * 返回JSON数据到客服端
	 * @param obj 需要转换为JSON的对象
	 */
	public void returnClientJSON(Object obj){
		try {
			String objcet = JSONObject.toJSONString(obj);
			log.info("返回JSON："+objcet);
			response.setContentType("text/html;charset=utf-8");
			response.getWriter().print(objcet);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	
	public void setUrlMenu(String urlMenu) {
		this.urlMenu = urlMenu;
	}

	public String getUrlMenu() {
		return urlMenu;
	}

	public void setBackurl(String backurl) {
		this.backurl = backurl;
	}

	public String getBackurl() {
		return backurl;
	}

	public void setMessageID(String messageID) {
		this.messageID = messageID;
	}

	public String getMessageID() {
		return messageID;
	}

	public void setParams(String params) {
		if(!StringUtils.isEmpty(params)) {
			try {
				params = URLEncoder.encode(params, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				log.info("URLEncoder错误", e);
			}
		}
		this.params = params;
	}

	public String getParams() {
		return params;
	}

	public void setRootDir(String rootDir) {
		this.rootDir = rootDir;
	}

	public String getRootDir() {
		return rootDir;
	}

	public static void setDistDir(String distDir) {
		BaseAction.distDir = distDir;
	}

	public  String getDistDir() {
		if(distDir==null)
		{
			//distDir=PropertyUtil.getPropertyValueByKey(DIST_DIR_KEY,request);
			if(System.getProperty("os.name").startsWith("Windows"))
			{
				//System.out.println(System.getProperty("os.name"));
				// distDir=PropertyUtil.getPropertyValueByKey(DIST_DIR_KEY,request);
				//System.out.println("linux upload path:"+System.getProperty(rootDir));
			}
			else
			{
				
				//System.out.println(System.getProperty("os.name2222"));
				//distDir=PropertyUtil.getPropertyValueByKey(LINUX_DIST_DIR_KEY,request);
			//	System.out.println("linux upload path:"+rootDir);
			}
		}
		return distDir;
	}
	
	public String getAdvDir() {
		if(advDir==null)
		{
			//distDir=PropertyUtil.getPropertyValueByKey(DIST_DIR_KEY,request);
			if(System.getProperty("os.name").startsWith("Windows"))
			{
				//System.out.println(System.getProperty("os.name"));
				//advDir=PropertyUtil.getPropertyValueByKey(ADV_DIR_KEY,request);
				//System.out.println("linux upload path:"+System.getProperty(rootDir));
			}
			else
			{
				
				//System.out.println(System.getProperty("os.name2222"));
				//advDir=PropertyUtil.getPropertyValueByKey(LINUX_ADV_DIR_KEY,request);
			//	System.out.println("linux upload path:"+rootDir);
			}
		}
		return advDir;
	}
}
